package com.bsdsma.fengheguaiapp.filter;

import com.bsdsma.fengheguaiapp.constants.TokenConstants;
import com.bsdsma.fengheguaiapp.jwt.JwtUtils;
import com.bsdsma.fengheguaiapp.utils.RedisMockUtils;
import com.bsdsma.fengheguaiapp.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * 登录状态校验
 */

@WebFilter(urlPatterns = "/api/*", asyncSupported = true)
@Slf4j
public class TokenFilter implements Filter {

    private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    private static final String NO_AUTH_KEY = "/noauth/";
    private static final String[] SKIP_PATHS = new String[]{
            "/api/auth/login",
            "/api/auth/register",
            "/api/v1/chat/**"
    };

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestURI = request.getRequestURI();

        log.info("拦截到请求：{}, Method: {}", requestURI, request.getMethod());

        // 检查是否需要验证
        if (this.check(requestURI)) {
            log.info("本次请求{}不需要处理", requestURI);
            filterChain.doFilter(request, response);
            return;
        }

        // 验证token
        String token = request.getHeader(TokenConstants.AUTHORIZE_TOKEN);
        if (!StringUtils.isBlank(token)) {
            try {
                Long uid = JwtUtils.getId(token);
                String realToken = RedisMockUtils.getUserToken(uid);
                if (token.equals(realToken)) {
                    request.setAttribute(TokenConstants.UID, uid);
                    filterChain.doFilter(request, response);
                    return;
                }
            } catch (Exception e) {
                log.error("Token验证失败", e);
            }
        }

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
    }

    public boolean check(String requestURI) {
        if (requestURI.contains(NO_AUTH_KEY)) {
            return true;
        }
        for (String url : SKIP_PATHS) {
            if (PATH_MATCHER.match(url, requestURI)) {
                return true;
            }
        }
        return false;
    }
}